let localUsername = getUrlValue("userName"), toUser;
let websocket = null, peer = null, onTheLine = false, layer, laytpl,localStream;
let blobs = [], mediaRecorder, mimeType = 'video/webm';
let recordPlayer = document.getElementById("replyBtn");
let mediaObj={ video: {width:370,height:550}, audio: true };
var PeerConnection = window.RTCPeerConnection ||
  window.mozRTCPeerConnection ||
  window.webkitRTCPeerConnection;
  const objData = {
    localStream: null,//本地视频流
    userPeer: null,//用户rtc
    offerOption: {
      offerToReceiveAudio: 1,
      offerToReceiveVideo: 1
    },
    layerIndex:null,
    msg:null,
    iceServers:{//穿透服务
      iceServers: [
          { url: ""}, // 
          {
            url: '',
            credential: 'p1',//密码
            username: 'u1'//用户名
          },
      ]
    }
  };
layui.use(['layer', 'laytpl'], function () {
  layer = layui.layer;
  laytpl = layui.laytpl;
  WebSocketInit();
  //视频通话
  document.getElementById('call').onclick = function (e) {
    toUser = document.getElementById('toUser').value;
    if (!toUser) {
      layer.msg("请先指定好友账号，再发起视频通话！", { icon: 5 });
      return;
    }
    if (objData.userPeer == null) {
      laytpl(document.getElementById('templet-video-box').innerHTML).render({ fromUser: localUsername, toUser: toUser}, function (html) {
        layer.open({
          title: false,
          move: ".move",
          type: 1,
          skin: 'layui-layer-demo', //样式类名
          closeBtn: 0, //不显示关闭按钮
          anim: 2,
          shade: 0,
          resize: false,
          content: html,
          success: async function (layero, index) {
            objData.layerIndex=index;
            $("#localVideo").addClass("layui-hide");
            $(".controls-v").addClass("layui-hide");
            $("#hangup").removeClass("layui-hide");
            $(".controls-box").addClass("opacity");
            // 创建视频源
            await createNative();
            await nativeMedia("remoteVideo");
            // 创建rtc
            await initPeer();
            websocket.send(JSON.stringify({
              type: "call_start",
              fromUser: localUsername,
              toUser: toUser,
            }));
            // 忙线标识
            onTheLine = true;
          }
        });
      })
    }

  }
  // 控制媒体设备
  $("body").on("click",".control-item",function(){
    let type=$(this).attr("type"),text;
    switch (type) {
      case "microphone"://麦克风
        // 获取音频轨道
        var audioTracks = objData.localStream.getAudioTracks();
        if ($(this).hasClass("open")) {
          $(this).removeClass("open").addClass("close");
          $(this).children(".control-item-text").text("麦克风已关");
          // 若存在音频轨道，则关闭麦克风
          if (audioTracks.length > 0) {
            audioTracks[0].enabled = false;
          }
        }else{
          $(this).removeClass("close").addClass("open");
          $(this).children(".control-item-text").text("麦克风已开");
          audioTracks[0].enabled = true;
        }
        break;
      case "loudspeaker"://扬声器
        let video=document.getElementById("remoteVideo");
        if ($(this).hasClass("open")) {
          $(this).removeClass("open").addClass("close");
          $(this).children(".control-item-text").text("扬声器已关");
          video.muted=true;
        }else{
          $(this).removeClass("close").addClass("open");
          $(this).children(".control-item-text").text("扬声器已开");
          video.muted=false;
        }
        break;
      case "camera"://摄像头
        // 获取视频频轨道
        var videoTracks = objData.localStream.getVideoTracks();
        if ($(this).hasClass("open")) {
          $(this).removeClass("open").addClass("close");
          $(this).children(".control-item-text").text("摄像头已关");
          if (videoTracks.length > 0) {
            videoTracks[0].enabled = false;
          }
        }else{
          $(this).removeClass("close").addClass("open");
          $(this).children(".control-item-text").text("摄像头已开");
          videoTracks[0].enabled = true;
        }
        break;
      default:
        break;
    }
  })
});


/* WebSocket */
function WebSocketInit() {
  //判断当前浏览器是否支持WebSocket
  if ('WebSocket' in window) {
    // websocket = new WebSocket("wss://localhost:5500/wss/" + localUsername); //
    websocket = new WebSocket("wss://localhost:5500/wss/" + localUsername,["123"]); //
  } else {
    alert("当前浏览器不支持WebSocket！");
  }

  //连接发生错误的回调方法
  websocket.onerror = function (e) {
    console.error(e)
    alert("WebSocket连接发生错误！");
  };

  //连接关闭的回调方法
  websocket.onclose = function () {
    console.error("WebSocket连接关闭");
  };

  //连接成功建立的回调方法
  websocket.onopen = function () {
    console.log("WebSocket连接成功");
  };

  //接收到消息的回调方法
  websocket.onmessage = async function (event) {
    let msg = JSON.parse(event.data);
    console.log(msg)
    switch (msg.type) {
      case 'hangup'://挂断
        onHangup(msg);
        break;
      case 'call_start'://收到通话请求
      
        call_start(msg);
        break;
      case 'call_back'://接听返回（收到被呼叫方的返回信息）
        call_back(msg);
        break;
      case 'offer':
        onOffer(msg);
        break;
      case 'answer':
        onAnswer(msg);
        break;
      case '_ice':
        on_ice(msg);
        break;
      default:
        break;
    }
  }
}
//创建本地流全局放置
async function createNative() {
  objData.localStream = await navigator.mediaDevices.getUserMedia(mediaObj);
}
// 本地视频流打开
function nativeMedia(id) {
  let video = document.getElementById(id);
  // 旧的浏览器可能没有srcObject
  if ("srcObject" in video) {
    video.srcObject = objData.localStream;
  } else {
    video.src = window.URL.createObjectURL(objData.localStream);
    video.volume = 0
  }
  // eslint-disable-next-line no-unused-vars
  video.onloadedmetadata = function (e) {
    video.play();
  };
}
//初始化 RTC
function initPeer() {
  let peer_tep = new PeerConnection(objData.iceServers);
  peer_tep.addStream(objData.localStream);
  peer_tep.onicecandidate = function (event) {
    // console.log("监听ice候选信息", event.candidate)
    if (event.candidate) {
      websocket.send(JSON.stringify({
        type: '_ice',
        toUser: toUser||objData.msg.fromUser,
        fromUser: localUsername,
        iceCandidate: event.candidate
      }));
    } else {
      // console.log("ICE收集已经完成")
    }
  };
  peer_tep.onaddstream = (event) => {
    document.getElementById('remoteVideo').srcObject = event.stream;
  };
  objData.userPeer= peer_tep;
}
// 收到通话请求
function call_start(msg){
  if (onTheLine) {
    // 忙线返回信息给对方
    websocket.send(JSON.stringify({
      type: "call_back",
      toUser: msg.fromUser,
      fromUser: localUsername,
      msg: "2"
    }));
    return;
  }
  layer.closeAll();
  laytpl(document.getElementById('templet-video-box').innerHTML).render({ toUser: msg.fromUser, }, function (html) {
    layer.open({
      title: false,
      move: ".move",
      type: 1,
      skin: 'layui-layer-demo', //样式类名
      closeBtn: 0, //不显示关闭按钮
      anim: 2,
      shade: 0,
      resize: false,
      content: html,
      success: async function (layero, index) {
        $("#localVideo").addClass("layui-hide");
        $(".controls-v").addClass("layui-hide");
        $("#jujue").removeClass("layui-hide");
        $("#answer").removeClass("layui-hide");
        $(".controls-box").addClass("opacity");
        // 创建视频源
        await createNative();
        await nativeMedia("remoteVideo");
        objData.layerIndex=index;
        objData.msg=msg;
        onTheLine = true;
      }
    });
  })
}
// 接听返回（收到被呼叫方的返回信息）
async function call_back(d){
  
  // debugger;
  if (d.msg === "1") {
    $("#localVideo").removeClass("layui-hide");
    $(".controls-v").removeClass("layui-hide");
    $(".user-msg").addClass("layui-hide");
    $("#hangup").removeClass("layui-hide");
    $("#answer").addClass("layui-hide");
    $("#jujue").addClass("layui-hide");
    $(".controls-box").removeClass("opacity");
    // 展示本地视频
    await nativeMedia("localVideo");
    recodeVideo(objData.localStream,d);
    //创建offer
    let offer = await objData.userPeer.createOffer(objData.offerOption);
    
    //远程发送到服务器 并转发到其他的客户端
    let params = { type: "offer", "fromUser": localUsername, "toUser": toUser, offer: offer, fileNameTime:d.fileNameTime};
    websocket.send(JSON.stringify(params));
    //设置本地描述
    await objData.userPeer.setLocalDescription(offer)
    
  } else if (d.msg === "0") {
    layer.msg(toUser + "拒绝视频通话", { icon: 5 });
    onHangup();
  } else if (d.msg === "2") {
    $("#hangup").remove();
    layer.msg(toUser + "忙线中", { icon: 5 });
    setTimeout(function(){layer.close(objData.layerIndex);onHangup();},3000)
  } else {
    layer.msg(msg, { icon: 5 });
    onHangup();
  }
}
// offer
async function onOffer(d){
  $("#localVideo").removeClass("layui-hide");
  $(".user-msg").addClass("layui-hide");
  $(".controls-v").removeClass("layui-hide");
  $(".controls-hangup").addClass("layui-hide");
  $(".controls-answer").addClass("layui-hide");
  $("#hangup").removeClass("layui-hide");
  $(".controls-box").removeClass("opacity");
  // 展示本地视频
  await nativeMedia("localVideo");
  recodeVideo(objData.localStream,d);
  await objData.userPeer.setRemoteDescription(d.offer);//存取呼叫方远程描述
  // 接收端创建 answer
  let answer = await objData.userPeer.createAnswer();
  
  //发送到呼叫端 answer
  let params = { type: "answer", "fromUser": localUsername, "toUser": d.fromUser, answer: answer };
  websocket.send(JSON.stringify(params));
  // 接收端设置本地 answer 描述
  await objData.userPeer.setLocalDescription(answer);
}
// answer
async function onAnswer(d){
  
  //呼叫方与被呼叫方建立连接
  objData.userPeer.setRemoteDescription(d.answer);
}
// ice
async function on_ice(d){
  // 添加远程描述ice
  await objData.userPeer.addIceCandidate(d.iceCandidate);
}
// 挂断
function onHangup(){
  stopRecordVideo();
  if (document.getElementById('localVideo').srcObject||objData.localStream) {
    const videoTracks = objData.localStream.getVideoTracks()||document.getElementById('localVideo').srcObject.getVideoTracks();//
    const audioTracks = objData.localStream.getAudioTracks()||document.getElementById('localVideo').srcObject.getAudioTracks();
    videoTracks.forEach(videoTrack => {
      // 关闭摄像头
      videoTrack.stop();
      document.getElementById('localVideo').srcObject?document.getElementById('localVideo').srcObject.removeTrack(videoTrack):"";
    });
    audioTracks.forEach(audioTrack => {
      // 关闭麦克风
      audioTrack.stop();
      document.getElementById('localVideo').srcObject?document.getElementById('localVideo').srcObject.removeTrack(audioTrack):"";
    });
  }

  if (objData.userPeer) {
    objData.userPeer.ontrack = null;
    objData.userPeer.onremovetrack = null;
    objData.userPeer.onremovestream = null;
    objData.userPeer.onicecandidate = null;
    objData.userPeer.oniceconnectionstatechange = null;
    objData.userPeer.onsignalingstatechange = null;
    objData.userPeer.onicegatheringstatechange = null;
    objData.userPeer.onnegotiationneeded = null;

    objData.userPeer.close();
    objData.userPeer = null;
  }
  onTheLine = false;
  document.getElementById('localVideo').srcObject = null;
  document.getElementById('remoteVideo').srcObject = null;
  layer.close(objData.layerIndex);
}
// 接听
$("body").on("click","#answer",async function(){
  // 创建rtc
  await initPeer();
  // 响应信息给呼叫方
  websocket.send(JSON.stringify({
    type: "call_back",
    toUser: objData.msg.fromUser,
    fromUser: localUsername,
    fileNameTime: objData.msg.fileNameTime,
    msg: "1"
  }));
})
// 拒绝
$("body").on("click","#jujue",function(){
  websocket.send(JSON.stringify({
    type: "call_back",
    toUser: objData.msg.fromUser,
    fromUser: localUsername,
    msg: "0"
  }));
  layer.close(objData.layerIndex);
  onTheLine = false;
})
// 挂断
$("body").on("click","#hangup",function(){
  // if (onTheLine) {
    
  // }
  //挂断同时，通知对方
  websocket.send(JSON.stringify({
    type: "hangup",
    fromUser: localUsername,
    toUser:toUser|| objData.msg.fromUser
  }));
  onHangup();
})

function getUrlValue(name) {
  let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
  let r = window.location.search.substring(1).match(reg);
  if (r != null) return decodeURI(r[2]);
  return null;
}
// 录制视频
function recodeVideo(stream,d) {
  // 录制需要用到MediaRecorder
  // 我们需要把上面获取到的流stream传入，并且配置类型
  let time=d.fileNameTime;
  if (mediaRecorder == null) {
    let fileName=`${d.fromUser}_${d.toUser||toUser}_${time}_${localUsername}.webm`
    blobs=[],recordPlayer.src=""
    mediaRecorder = new MediaRecorder(stream, {
      mimeType: "video/webm;codecs=h264"
    });
    mediaRecorder.ondataavailable = (e) => {
      let file = new File([e.data], mimeType);
      let formData = new FormData();
      
      formData.append('multipartFile', file);
      formData.append('appendFileName', fileName);
      $.ajax({
          type:"POST",
          url: "https://192.168.2.225:30009/roomrtc/appendFile",
          data: formData,
          processData: false,
          contentType: false,
          success:function (){
             console.log("上传视频成功!");
           },
          error : function() {
            console.log("上传视频失败!");
          }
       });
    };
    mediaRecorder.start(3000);
    mediaRecorder.onstop = function(e) {
      setTimeout(function(){
        $.ajax({
          type:"POST",
          url: "https://192.168.2.225:30009/roomrtc/startConvertToMp4",
          data: {appendFileName:fileName},
          success:function (){
             console.log("上传视频成功!");
           },
          error : function() {
            console.log("上传视频失败!");
          }
       });
      },3000)
      
      console.log("# 录制终止 ...");
      // const blob = new Blob(blobs, {
      //   type: mimeType
      // });
      // console.log(blob)
      // recordPlayer.src = URL.createObjectURL(blob);
      // recordPlayer.play();
      // const fullBlob = new Blob(_chunks);
      // const blobURL = window.URL.createObjectURL(fullBlob);
      // console.log("blob is ?, size="+parseInt(fullBlob.size/1024)+"KB. "); console.log(fullBlob);
      // console.log("blobURL =" + blobURL);
      // //saveFile(blobURL);
      // uploadFile(fullBlob);
    }
  }
}
// 结束录制
function stopRecordVideo() {
  if (mediaRecorder) { 
    mediaRecorder.stop();
    mediaRecorder = null;
     
  }
}
